package cz.muni.fi.pb138.gscholarinfo.classes;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.LinkedList;
import java.util.List;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/*
 * Static class GSUtils
 * 
 * Specific IOException with the message "HTTP Error Code 503 Service Unavailable"
 * occurs when Google denies access to scholar.google.com believing a script is
 * trying to reach the site. After several hours the IP gets unblacklisted.
 */

public class GSUtils {
    
    private static String cookie = "";
    
    private GSUtils() {}
    
    /**
     * Find all <code>author</code>'s publications.
     * 
     * @param author author to search for
     * @return author's publications
     * @throws IOException when an IO error occured
     */
    public static AuthorPublications searchAuthorPublications(Author author) throws IOException
    {
        if (cookie.equals(""))
            setCookie();
        
        URL url = null;
        URLConnection con = null;
        InputStream pageStream = null;
        AuthorPublications autPubs = null;
        Document doc = null;
        
        int parsed = 0;
        try {
            do {
                url = new URL("http://scholar.google.com/citations?user=" + author.getGoogleId() + "&amp;hl=en&view_op=list_works&cstart=" + String.valueOf(parsed));
                
                con = url.openConnection();
                con.setRequestProperty("User-agent", "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0)");
                con.setRequestProperty("Cookie", cookie);
                                
                con.connect();
                
                //Html error 503
                if (con.getHeaderField(0).split(" ")[1].equals("503"))
                    throw new IOException("HTTP Error Code 503 Service Unavailable");
                
                pageStream = con.getInputStream();

                doc = Jsoup.parse(pageStream, "UTF-8", url.toString());

                //Every element has one publication
                Elements pubs = doc.select("[class=cit-table item]");
                
                if (autPubs == null)
                    autPubs = new AuthorPublications(author);
                
                //Iterate over all the publications
                for (Element item : pubs) {
                    //
                    Publication pub = parsePublicationFromAuthorPage(item);
                    if (pub != null)
                        autPubs.addPublication(pub);            
                    //
                }
                
                parsed += 20;
            } while (!doc.getElementsContainingText("Next >").isEmpty());
        } catch (MalformedURLException ignored) { }
        finally {
            if (pageStream != null)
                try { pageStream.close(); } catch (IOException ignored) {}
        }
        
        return autPubs;
    }
    
    /**
     * Find all authors matching <code>author</code>.
     * 
     * @param author author to search for
     * @return Authors in Author class encapsulation
     */
    public static List<Author> searchAuthor(String author) throws IOException
    {
        if (cookie.equals(""))
            setCookie();
        
        URL url = null;
        URLConnection con = null;
        InputStream pageStream = null;
        Document doc = null;
        List<Author> authors = new LinkedList<Author>();

        //Convert the query to UTF-8 format
        StringBuilder query = new StringBuilder();
        Charset charset = Charset.forName("UTF-8");
        byte[] encodedBytes = author.replace(' ', '+').getBytes(charset);
        for (int i = 0; i < encodedBytes.length; i++)
        {
            query.append('%');
            query.append(String.format("%2X", encodedBytes[i]));
        }
        
        url = new URL("http://scholar.google.com/citations?hl=en&view_op=search_authors&mauthors=" + query);
        
        boolean lastPage = false;
        try {
            do {
                con = url.openConnection();
                con.setRequestProperty("User-agent", "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0)");
                con.setRequestProperty("Cookie", cookie);

                con.connect();
                
                //Html error 503
                if (con.getHeaderField(0).split(" ")[1].equals("503"))
                    throw new IOException("HTTP Error Code 503 Service Unavailable");
                
                pageStream = con.getInputStream();

                doc = Jsoup.parse(pageStream, "UTF-8", url.toString());
                
                //Get doubles of authors in every element
                Elements eles = doc.select("[class=g-section g-tpl-50-50]");
                
                //Parse the authors
                Author aut = null;
                Element ele = null;
                String href = null;
                for (Element item : eles)
                {
                    ele = item.select("[class=g-unit g-first]").get(0);
                    aut = new Author();
                    aut.setName(ele.select("[class=cit-dark-large-link]").get(0).text());
                    href = ele.select("[class=cit-dark-large-link]").get(0).attr("href");
                    href = href.split("user=")[1];
                    href = href.substring(0, href.indexOf('&'));
                    aut.setGoogleId(href);
                    authors.add(aut);
                    
                    if (!item.select("[class=g-unit]").isEmpty())
                    {
                        ele = item.select("[class=g-unit]").get(0);
                        aut = new Author();
                        aut.setName(ele.select("[class=cit-dark-large-link]").get(0).text());
                        href = ele.select("[class=cit-dark-large-link]").get(0).attr("href");
                        href = href.split("user=")[1];
                        href = href.substring(0, href.indexOf('&'));
                        aut.setGoogleId(href);
                        authors.add(aut);
                    }
                }

                //Move to next page or finish
                if ((eles = doc.getElementsContainingOwnText("Next >")).isEmpty())
                    lastPage = true;
                else
                {
                    url = new URL("http://scholar.google.com" + eles.get(0).attr("href"));
                }

            } while (!lastPage);
        } catch (MalformedURLException ignored) { }
        finally {
            if (pageStream != null)
                try { pageStream.close(); } catch (IOException ignored) {}
        }
        
        return authors;
        /*
        <div class="g-section g-tpl-50-50">
         <div class="g-unit g-first">
          <table style="margin: 5px 0px;">
           <tbody>
            <tr>
             <td style="text-align: center; padding: 0px 5px;width: 150px;"><a href="/citations?user=nW188XwAAAAJ&amp;hl=en"><img src="/citations?view_op=view_photo&amp;user=nW188XwAAAAJ&amp;citpid=1" width="126" height="150" /></a></td>
             <td valign="top"><a class="cit-dark-large-link" href="/citations?user=nW188XwAAAAJ&amp;hl=en"><strong>Adam </strong>Wagstaff</a><br />World Bank<br />Verified email at worldbank.org<br />Cited by 11499<br /></td>
            </tr>
           </tbody>
          </table>
         </div>
         <div class="g-unit">
          <table style="margin: 5px 0px;">
           <tbody>
            <tr>
             <td style="text-align: center; padding: 0px 5px;width: 150px;"><a href="/citations?user=tbHm4yoAAAAJ&amp;hl=en"><img src="/citations?view_op=view_photo&amp;user=tbHm4yoAAAAJ&amp;citpid=1" width="117" height="150" /></a></td>
             <td valign="top"><a class="cit-dark-large-link" href="/citations?user=tbHm4yoAAAAJ&amp;hl=en">Michael A. <strong>Adams</strong></a><br />Professor of Biomechanics, University of Bristol, UK<br />Verified email at bris.ac.uk<br />Cited by 8578<br /></td>
            </tr>
           </tbody>
          </table>
         </div>
        </div>
        */
    }
    
    /**
     * Searches for the publications that cited <code>publication</code>.
     * 
     * @param publication Publication to search for
     * @param count Number of publications to parse, -1 if all
     * @return <code>count</code> citing publications
     */
    public static PublicationCitations searchPublicationCitations(Publication publication, int count) throws IOException
    {
        if ((publication == null) || ((count < 1) && (count != -1)))
            throw new IllegalArgumentException("searchPublicationCItations");
            
        if (cookie.equals(""))
            setCookie();
        
        if (publication.getGoogleId() == null)
            return null;
        
        URL url = null;
        URLConnection con = null;
        InputStream pageStream = null;
        PublicationCitations pubCit = null;
        //
        String tmp;
        //
        
        int results = -1;
        int parsed = 0;
        try {
            do {
                url = new URL("http://scholar.google.com/scholar?cites=" + publication.getGoogleId() + "&as_sdt=2005&sciodt=0,5&num=100&hl=en&start=" + parsed);

                con = url.openConnection();
                con.setRequestProperty("User-agent", "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0)");
                con.setRequestProperty("Cookie", cookie);

                con.connect();
                
                //Html error 503
                if (con.getHeaderField(0).split(" ")[1].equals("503"))
                    throw new IOException("HTTP Error Code 503 Service Unavailable");
                
                pageStream = con.getInputStream();

                Document doc = Jsoup.parse(pageStream, "UTF-8", url.toString());

                //
                tmp = doc.toString();
                //
                
                //Get the number of results
                if (results == -1)
                {
                    if (!doc.getElementsContainingOwnText("1 result").isEmpty())
                        results = 1;
                    else {
                        String res = doc.getElementsContainingOwnText("results").select("[id=gs_ab_md]").first().text();
                        if (res.charAt(0) == 'A')
                            res = res.substring(6);

                        res = res.replaceAll(",", "");
                        res = res.substring(0, res.indexOf(' '));

                        results = Integer.valueOf(res);
                    }
                }

                Elements eles = null;
                //Each publication in an element
                eles = doc.select("div").select("[class=gs_r]");

                //Google has a limit of 1000 results per search
                if ((eles == null) && (parsed == 1000))
                    break;
                
                if (pubCit == null)
                    pubCit = new PublicationCitations(publication);
                
                for (Element item : eles) {
                    //
                    Publication pub = parsePublicationFromPubSearch(item);
                    if (pub != null)
                        pubCit.addCitedIn(pub);
                    //
                    parsed++;
                    
                    if (parsed == count)
                        break;
                }
                
            } while ((results > parsed) && (parsed != count));
            
        } catch (MalformedURLException ignored) { }
        finally {
            if (pageStream != null)
                pageStream.close();
        }
        
        return pubCit;
    }
    
    private static void setCookie() throws IOException
    {
        URL url = null;
        URLConnection con = null;
        
        try {
            url = new URL("http://scholar.google.com/");
            con = url.openConnection();
            
            con.setRequestProperty("User-agent", "Mozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20100101 Firefox/12.0");
            con.connect();
            
            //Html error 503
            if (con.getHeaderField(0).split(" ")[1].equals("503"))
                throw new IOException("HTTP Error Code 503 Service Unavailable");
            
            List<String> tmpCookies = con.getHeaderFields().get("Set-Cookie");
            
            for (String item : tmpCookies)
            {
                if (!cookie.equals(""))
                    cookie += "; ";
                
                cookie += item.substring(0, item.indexOf("; expires"));
            }
            
        } catch (MalformedURLException ignored) { }
    }
    
    private static Publication parsePublicationFromPublicationPage(URL url) throws IOException
    {
        URLConnection con = null;
        InputStream pageStream = null;
        Document doc = null;
        String tmp = null;
        Publication pub = new Publication();
        
        try {
            con = url.openConnection();
            con.setRequestProperty("User-agent", "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0)");
            con.setRequestProperty("Cookie", cookie);

            con.connect();
            //Html error 503
            if (con.getHeaderField(0).split(" ")[1].equals("503"))
                throw new IOException("HTTP Error Code 503 Service Unavailable");
            
            pageStream = con.getInputStream();
            doc = Jsoup.parse(pageStream, "UTF-8", url.toString());
            
            //The table with title, authors and year
            Element table = doc.select("#main_sec").get(0);
                                    
            //
            //tmp = table.toString();
            //
            
            //Set title
            if (table.select("#title").first().children().isEmpty())
                pub.setTitle(table.select("#title").first().text());
            else    
                pub.setTitle(table.select("#title").first().child(0).text());
            
            //Set authors
            Elements eles = table.select("[class=g-section]");
            String[] authors = null;
            for (Element item : eles)
            {
                if ((item.child(0).text().equals("Authors")) || (item.child(0).text().equals("Inventors"))) {
                    authors = item.child(1).text().split(", ");
                    break;
                }
            }
            for (int i = 0; i < authors.length; i++)
                pub.addAuthor(authors[i]);
            
            //Set year
            if (!(eles = table.select("#pubdate_sec")).isEmpty()) {
                tmp = eles.first().child(1).text();
                if (tmp.length() > 4)
                    tmp = tmp.substring(0, 4);
                pub.setYear(Integer.valueOf(tmp));
            }
            else
                pub.setYear(0);
            
            //
            //tmp = table.toString();
            //
            
            //The table with number of citations and Google ID
            if ((table = doc.getElementById("scholar_sec")) != null)
            {
                pub.setCitedTimes(Integer.valueOf(table.child(1).child(0).text().substring(9)));
                pub.setGoogleId(table.child(1).child(0).attr("href").split("cites=")[1]);
            }
            else
                pub.setCitedTimes(0);
                        
        } catch (IndexOutOfBoundsException ex) {
            return null;
        } catch (NullPointerException ex) {
            return null;
        } finally {
            if (pageStream != null)
                try { pageStream.close(); } catch (IOException ignored) {}
        }
        
        return pub;
        
        /*
        <div class="g-section cit-fieldbox" id="main_sec">
            <u></u>
            <i></i>
            <div class="cit-dl">
                <div class="cit-dt">Title</div>
                <div class="cit-dd">
                    <div id="title">
                        <a style="text-decoration:none" href="http://www.muni.cz/research/publications/746041">DEB Platform tools for effective development of WordNets in application to PolNet</a>
                    </div>
                </div>
                <div class="g-section">
                    <div class="cit-dt">Authors</div>
                    <div class="cit-dd">Karel Pala, Z Vetulani, A Hor&aacute;k, A Rambousek, Pawe� Konieczka, Jacek Marciniak, Tomasz Obr�bski, Przemys�aw Rzepecki, Justyna Walkowska</div>
                </div>
                <div class="g-section" id="pubdate_sec">
                    <div class="cit-dt">Publication date</div>
                    <div class="cit-dd">2007</div>
                </div>
                <div class="g-section" id="venue_sec">
                    <div class="cit-dt">Journal name</div>
                    <div class="cit-dd">Human Language Technologies as a Challenge for Computer Science and Linguistics, Proceedings of 3rd Language and Technology Conference, Poznan</div>
                </div>
                <div class="g-section" id="pages_sec">
                    <div class="cit-dt">Pages</div>
                    <div class="cit-dd">514-518</div>
                </div>
                <div class="g-section" id="description_sec">
                    <div class="cit-dt">Description</div>
                    <div class="cit-dd">
                        The objective of this paper is the presentation of DEB Platform Tools and their utility in creation 
                        <br /> of WordNet ontology resources. These tools have been elaborated at Masaryk University as 
                        <br /> a result of experiences coming from creation of Czech WordNet. This paper presents the benefits 
                        <br /> of introducing the tools into the process of production of Polish WordNet within the PolNet project 
                        <br /> (at Adam Mickiewicz University). 
                    </div>
                </div>
            </div>
            <i></i>
            <u></u>
        </div>
        */
    }
    
    /**
     * TODO: (optional) Try to read the year of the publication from the description / publisher
     */
    private static Publication parsePublicationFromAuthorPage(Element publication) throws IOException
    {        
        //
        //String tmp = publication.toString();
        //
        
        Publication pub = new Publication();
       
        try {
        //Title & authors
        pub.setTitle(publication.select("[id=col-title]").first().child(0).text());
        
        String[] authors = publication.select("[id=col-title]").first().children().select("span").first().text().split(", ");
        //Not all authors may be on the author page
        if (authors[authors.length-1].indexOf("...") > -1)
        {
            try {
                return parsePublicationFromPublicationPage(new URL("http://scholar.google.com" + publication.select("[id=col-title]").get(0).child(0).attr("href")));
            } catch (MalformedURLException ignored) { }
        }
        for (int i = 0; i < authors.length; i++)
            pub.addAuthor(authors[i]);
        
        //Google ID & times cited
        if ((!publication.select("[id=col-citedby]").first().children().isEmpty()) && (publication.select("[id=col-citedby]").first().child(0).attr("style").indexOf("line-through") == -1))
        {
            pub.setGoogleId(publication.select("[id=col-citedby]").first().child(0).attr("href").split("cites=")[1]);
            pub.setCitedTimes(Integer.valueOf(publication.select("[id=col-citedby]").first().child(0).text()));
        }
        else
            pub.setCitedTimes(0);
        
        //Year
        if (!publication.select("[id=col-year]").first().text().equals(""))
            pub.setYear(Integer.valueOf(publication.select("[id=col-year]").first().text()));
        else
            pub.setYear(0);
        
        //return pub;
        } catch (IndexOutOfBoundsException ex) {
            return null;
        } catch (NullPointerException ex) {
            return null;
        }
        
        return pub;
        /*
        <tr class="cit-table item">
            <td id="col-select">
                <input type="checkbox" name="s" value="53SGwowAAAAJ:-f6ydRqryjwC" />
            </td>
        <td id="col-title">
            <a href="/citations?view_op=view_citation&amp;hl=en&amp;user=53SGwowAAAAJ&amp;citation_for_view=53SGwowAAAAJ:-f6ydRqryjwC" class="cit-dark-large-link">Perspectives on plant competition.</a>
            <br />
            <span class="cit-gray">JB Grace, D Tilman</span>
            <br />
            <span class="cit-gray">Perspectives on plant competition.</span>
        </td>
        <td id="col-citedby"><a class="cit-dark-link" href="http://scholar.google.com/scholar?oi=bibs&amp;hl=en&amp;cites=8588375490788847649,17129660902539361830,2360839626560732451,13985398372446809585,2596625623269834389,9380895676885113029,13693174468225324937,13529664069318176484,4203069890938652664,9363767398667323429,591768566631870480,9897515839711589487">1483</a></td>
        <td id="col-asterisk">
            <span style="font-size:120%;cursor:pointer;color:#00c" onclick="citToggleNearBox(this,'May include citations to different articles','/citations?view_op\x3dview_citation\x26amp;hl\x3den\x26amp;user\x3d53SGwowAAAAJ\x26amp;citation_for_view\x3d53SGwowAAAAJ:-f6ydRqryjwC','View','/intl/en/scholar/citations.html#mayincludemismatched','Learn more')">∗</span>
        </td>
        <td id="col-year">1990</td>
        </tr> 
        */
        
        /*
        <tr class="cit-table item">
            <td id="col-select">
                <input type="checkbox" name="s" value="hW9w-AoAAAAJ:L8Ckcad2t8MC"/>
            </td>
            <td id="col-title">
                <a href="/citations?view_op=view_citation&amp;hl=en&amp;user=hW9w-AoAAAAJ&amp;citation_for_view=hW9w-AoAAAAJ:L8Ckcad2t8MC" class="cit-dark-large-link">Adam. Migrating Cornetto Lexicon to New XML Database Engine</a>
                <br>
                <span class="cit-gray">A Horák, A Rambousek</span>
                <br>
                <span class="cit-gray">6th International Global Wordnet Conference Proceedings, 305-311</span>
            </td>
            <td id="col-citedby"></td>
            <td id="col-asterisk"></td>
            <td id="col-year"></td>
        </tr>
        */
    }
    
    private static Publication parsePublicationFromPubSearch(Element pub)
    {
        //
        //String tmp = pub.toString();
        //
        
        Publication publication = new Publication();
        
        try {
        //Title
        if (pub.select("h3").first().children().select("a").isEmpty())
            publication.setTitle(pub.select("h3").first().ownText());
        else
            publication.setTitle(pub.select("h3").first().children().select("a").first().text());
        
        //Authors
        String temp = pub.select("[class=gs_a]").first().text();
        String[] authors = temp.split(" - ")[0].split(", ");
        for (int i = 0; i < authors.length; i++)
        {
            authors[i] = authors[i].replaceAll("…", "");
                
            publication.addAuthor(authors[i]);
        }
        
        //Year
        if (temp.indexOf(" - ") != -1)
            temp = temp.split(" - ")[1];
        if (temp.indexOf(", ") != -1) {
            authors = temp.split(", ");
            temp = authors[authors.length-1];
        }
        try {
            publication.setYear(Integer.valueOf(temp));
        } catch (NumberFormatException ex) {
            publication.setYear(0);
        }
        
        //Google ID
        if (!pub.select("[class=gs_fl]").isEmpty()) {
            Element citations = pub.select("[class=gs_fl]").first().child(0);
            temp = citations.attr("href");
            if (temp.indexOf("cites=") != -1)
            {
                temp = temp.substring(temp.indexOf("cites=") + 6, temp.indexOf('&'));
                publication.setGoogleId(temp);
        
                //Cited times
                publication.setCitedTimes(Integer.valueOf(citations.text().substring(9)));
            }
        }
            
        //return publication;
        } catch (IndexOutOfBoundsException ex) {
            return null;
        } catch (NullPointerException ex) {
            return null;
        }
        
        return publication;
        /*
        <div class="gs_r">
        <h3 class="gs_rt"><span class="gs_ctu">[CITATION]</span> Macroecology of microbes–biogeography of the Glomeromycota. Mycorrhiza</h3>
        <div class="gs_a">
        VB Chaudhary, MK Lau… - 2008 - Springer
        </div>
        <div class="gs_fl">
        <a href="/scholar?cites=1555388613786670641&amp;as_sdt=2005&amp;sciodt=0,5&amp;hl=en&amp;num=100">Cited by 8</a> - 
        <a href="/scholar?q=related:MRZxFLTZlRUJ:scholar.google.com/&amp;hl=en&amp;num=100&amp;as_sdt=2005&amp;sciodt=0,5">Related articles</a>
        </div>
        </div>
        */
        
        /*
        <div class="gs_r">
        <h3 class="gs_rt"><a href="http://www.sciencedirect.com/science/article/pii/S0272771404002422" onmousedown="return scife_clk(this.href,'','res','95')">The consequences of scale: assessing the distribution of benthic populations in a complex estuarine fjord</a></h3>
        <div class="gs_ggs gs_fl">
        <a href="http://www.sfos.uaf.edu/directory/faculty/schoch/consequencesofscale.pdf" onmousedown="return scife_clk(this.href,'gga','gga','95')"><span class="gs_ctg2">[PDF]</span> from uaf.edu</a> 
        <br />
        <a href="/scholar?q=info:PgY7KbsI5mkJ:scholar.google.com/&amp;output=instlink&amp;hl=en&amp;num=100&amp;as_sdt=2005&amp;sciodt=0,5&amp;scillfp=12793077954439330238">Get Fulltext at MU</a>
        </div>
        <div class="gs_a">
        MN Dethier… - Estuarine, Coastal and Shelf Science, 2005 - Elsevier
        </div>
        <div class="gs_rs">
        Evidence suggests that patterns of benthic community structure are functionally linked to 
        <br />estuarine processes and physical characteristics of the benthos. To assess these linkages 
        <br />for coarse-sediment shorelines, we used a spatially nested sampling design to quantify 
        <b> ...</b>
        </div>
        <div class="gs_fl">
        <a href="/scholar?cites=7630796218569524798&amp;as_sdt=2005&amp;sciodt=0,5&amp;hl=en&amp;num=100">Cited by 42</a> - 
        <a href="/scholar?q=related:PgY7KbsI5mkJ:scholar.google.com/&amp;hl=en&amp;num=100&amp;as_sdt=2005&amp;sciodt=0,5">Related articles</a> - 
        <a href="/scholar?cluster=7630796218569524798&amp;hl=en&amp;num=100&amp;as_sdt=2005&amp;sciodt=0,5">All 6 versions</a>
        </div>
        </div>
        */
        
        /*
        <div class="gs_r">
            <h3 class="gs_rt">
                <a href="http://onlinelibrary.wiley.com/doi/10.1111/j.1526-100X.2005.00072.x/full" onmousedown="return scife_clk(this.href,'','res','1')">
                    Restoration success: How is it being measured?
                </a>
            </h3>
        <div class="gs_ggs gs_fl">
            <a href="http://arbimon.uprrp.edu/weblab/Publications_files/Ruiz-Jaen%20and%20Aide%202005.pdf" onmousedown="return scife_clk(this.href,'gga','gga','1')"><span class="gs_ctg2">[PDF]</span> from uprrp.edu</a> 
            <br />
            <a href="/scholar?q=info:5Of_m2jKJcMJ:scholar.google.com/&amp;output=instlink&amp;hl=en&amp;num=100&amp;as_sdt=2005&amp;sciodt=0,5&amp;scillfp=12948998739837620212">Get Fulltext at MU</a>
        </div>
        <div class="gs_a">
            <a href="/citations?hl=en&amp;user=5JdTDMoAAAAJ&amp;oi=sra">MC Ruiz‐Jaen</a>, 
            <a href="/citations?hl=en&amp;user=kWkeHOEAAAAJ&amp;oi=sra">T Mitchell Aide</a> - Restoration Ecology, 2005 - Wiley Online Library
        </div>
        <div class="gs_rs">
        The criteria of restoration success should be clearly established to evaluate restoration 
        <br />projects. Recently, the Society of Ecological Restoration International (SER) has produced a 
        <br />Primer that includes ecosystem attributes that should be considered when evaluating 
        <b> ...</b>
        </div>
        <div class="gs_fl">
        <a href="/scholar?cites=14061867962176890852&amp;as_sdt=2005&amp;sciodt=0,5&amp;hl=en&amp;num=100">Cited by 220</a> - 
        <a href="/scholar?q=related:5Of_m2jKJcMJ:scholar.google.com/&amp;hl=en&amp;num=100&amp;as_sdt=2005&amp;sciodt=0,5">Related articles</a> - 
        <a href="http://direct.bl.uk/research/3F/11/RN172998986.html?source=googlescholar" onmousedown="return scife_clk(this.href,'','docdel','1')">BL Direct</a> - 
        <a href="/scholar?cluster=14061867962176890852&amp;hl=en&amp;num=100&amp;as_sdt=2005&amp;sciodt=0,5">All 13 versions</a>
        </div>
        </div>
        */
        
        /*
        <div class="gs_r">
            <h3 class="gs_rt">
                <span class="gs_ctc">[BOOK]</span>
                <a href="http://books.google.com/books?hl=en&amp;lr=&amp;id=NpkIF1IDqOMC&amp;oi=fnd&amp;pg=PR7&amp;ots=MPr5sYkdws&amp;sig=bDVac_pxMoL9yEsj90t57R05o7Q" class="yC0">
                    Vegetation Description and Data Analysis: A Practical Approach
                </a>
            </h3>
            <div class="gs_a">M Kent - 2011 - books.google.com</div>
            <div class="gs_rs">" Vegetation Description and Data Analysis: A Practical Approach," Second Edition is a fully <br>revised and up-dated edition of this key text. The book takes account of recent advances in <br>the field whilst retaining the original reader-friendly approach to the coverage of <b> ...</b></div>
            <div class="gs_fl">
                <a href="/scholar?cites=6183559701807394891&amp;as_sdt=2005&amp;sciodt=0,5&amp;hl=en">Cited by 1862</a> - 
                <a href="/scholar?q=related:S3Cmcclq0FUJ:scholar.google.com/&amp;hl=en&amp;as_sdt=2005&amp;sciodt=0,5">Related articles</a>   - 
                <a href="/scholar?q=info:S3Cmcclq0FUJ:scholar.google.com/&amp;output=instlink&amp;hl=en&amp;as_sdt=2005&amp;sciodt=0,5&amp;scillfp=11097107960022580762">Try to Get Fulltext at MU</a> - 
                <a href="/scholar?cluster=6183559701807394891&amp;hl=en&amp;as_sdt=2005&amp;sciodt=0,5">All 9 versions</a>
            </div>
        </div>
        */
        
        /*
        <div class="gs_r">
            <h3 class="gs_rt">
                <span class="gs_ctc">[PDF]</span> 
                <a href="http://hnk.ffzg.hr/bibl/ltc2011/book/papers/IER-2.pdf" class="yC0">
                    Information Extraction for Czech Based on Syntactic Analysis
                </a>
            </h3>
            <div class="gs_ggs gs_fl">
                <a href="http://hnk.ffzg.hr/bibl/ltc2011/book/papers/IER-2.pdf" class="yC1">
                    <span class="gs_ctg2">[PDF]</span> from ffzg.hr
                </a>
            </div>
            <div class="gs_a">V Baisa… - hnk.ffzg.hr</div>
            <div class="gs_rs">Abstract We present a complex pipeline of natural language processing tools for Czech that <br>perfonns extraction of basic facts presented in a text. The input for the tool is a plain text, the <br>output contains verb and noun phrases with basic semantic classiﬁcation. Automatic <b> ...</b></div>
            <div class="gs_fl">
                <a href="/scholar?q=related:shcnYHPRh9IJ:scholar.google.com/&amp;hl=en&amp;as_sdt=0,5&amp;sciodt=0,5">Related articles</a>
            </div>
        </div>
        */
    }
}
